package com.qianniu.napi.common.util;

import akka.actor.ActorRef;
import akka.actor.Props;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.base.Strings;
import com.qianniu.napi.admin.entity.English;
import com.qianniu.napi.admin.entity.MerchantApp;
import com.qianniu.napi.admin.entity.User;
import com.qianniu.napi.admin.entity.wxbean.AccessToken;
import com.qianniu.napi.admin.service.IEnglishService;
import com.qianniu.napi.admin.service.IMerchantAppService;
import com.qianniu.napi.admin.service.IRedisService;
import com.qianniu.napi.admin.service.IUserService;
import com.qianniu.napi.admin.service.akka.AKRealTemplate;
import com.qianniu.napi.admin.service.akka.AkkaServer;
import com.qianniu.napi.common.config.Constants;
import org.redisson.api.RList;
import org.redisson.api.RMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.awt.*;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;


/**
 * Created by chenxuebin on 16/8/10.
 */
public class WeixinUtil {

    private static final Logger logger = LoggerFactory.getLogger(WeixinUtil.class);

    private IUserService userService = (IUserService) SpringUtil.getBean("userServiceImpl");
//    private IRedisService redisService = (IRedisService) SpringUtil.getBean("redisServiceImpl");

    public static String getAccessToken() {
        IRedisService redisService = (IRedisService) SpringUtil.getBean("redisServiceImpl");
        String token = redisService.getWxtoken();
        return token;
    }

    public static String getAccessToken(String mpid) {
        IRedisService redisService = (IRedisService) SpringUtil.getBean("redisServiceImpl");
        String token = redisService.getWxtoken(mpid);
        return token;
    }

    public static AccessToken getAccessToken2(String appid, String appsecret) {
        AccessToken accessToken = null;

        String requestUrl = Constants.WEIXIN_TOKEN_URL.replace("APPID", appid).replace("APPSECRET", appsecret);
        String json = httpRequest(requestUrl, "GET", null);
        JSONObject jsonObject = JSON.parseObject(json);
        // 如果请求成功
        if (null != jsonObject) {
            try {
                accessToken = new AccessToken();
                accessToken.setAccessToken(jsonObject.getString("access_token"));
                accessToken.setExpiresIn(Integer.valueOf(Integer.valueOf(jsonObject.get("expires_in").toString())));
            } catch (Exception e) {
                accessToken = null;
                // 获取token失败
                System.out.println("获取token失败 errcode:{} errmsg:{}");
            }
        }
        return accessToken;
    }

    public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
//			jsonObject = JSONObject.fromObject(buffer.toString());
            return buffer.toString();
        } catch (ConnectException ce) {
            System.out.println("Weixin server connection timed out.");
        } catch (Exception e) {
            System.out.println("error.");
        }
//		return jsonObject;
        return null;
    }

    // 获取用户信息
    public static JSONObject getWXUserInfo(String openid, String mpid) {

        String userInfoUrl = Constants.WEIXIN_USER_INFO_URL.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken(mpid))
                .replace("OPENID", openid);
        return JSON.parseObject(HttpUtils.httpGet(userInfoUrl));
    }

    public static void saveOrUpdateUser(String openid, String mpid, String parentOpenId, Integer originType, String[] qrscene) {

        IUserService userService = (IUserService) SpringUtil.getBean("userServiceImpl");
        IMerchantAppService merchantAppService = (IMerchantAppService) SpringUtil.getBean("merchantAppServiceImpl");
        User updateuser = new User();
        JSONObject userObj = WeixinUtil.getWXUserInfo(openid, mpid);
        logger.debug("userInfo:" + userObj.toJSONString());
        Map<String, Object> map = new HashMap<String, Object>();
        map.clear();
        map.put("openid", userObj.getString("openid"));

        List<User> list = userService.selectByMap(map);
        User user = list == null || list.size() == 0 ? null : list.get(0);

        if (user == null
                || Strings.isNullOrEmpty(user.getOpenid())) {
            user = new User();
            user.setOpenid(userObj.getString("openid"));
            user.setUnionid(userObj.getString("unionid"));
            user.setNickName(userObj.getString("nickname"));
            user.setGender(userObj.getString("sex"));
            user.setLanguage(userObj.getString("language"));

            user.setCity(userObj.getString("city"));
            user.setProvince(userObj.getString("province"));
            user.setCountry(userObj.getString("country"));
            user.setAvatarPic(userObj.getString("headimgurl"));
            user.setSubscribeTime(userObj.getLong("subscribe_time"));
            user.setUserType(Constants.USER_TYPE_COMMON);
//                        user.setOrigin(origin);
            user.setOriginType(originType);//
            user.setIsFocus(1);//关注
            user.setIp(ObjectUtil.getIP());// 关注
            MerchantApp mapp = merchantAppService.selectById(mpid);
            user.setMid(mapp.getMid());// 关注
            user.setMpid(mapp.getId());// 关注

            userService.insert(user);
        }

        if (userObj == null || Strings.isNullOrEmpty(userObj.getString("openid"))) {
            map.clear();
            logger.error("update user for cancel for openid=" + openid);
            updateuser.setOpenid(openid);
            updateuser.setIsFocus(0);

            userService.update(updateuser, new EntityWrapper<User>().eq("openid", openid));

        } else if (!userObj.getString("headimgurl").equals(user.getAvatarPic())
                || !userObj.getString("nickname").equals(user.getNickName())
                || (userObj.getString("unionid") != null && !userObj.getString("unionid").equals(user.getUnionid()))
                || !userObj.getString("sex").equals(user.getGender())
        ) {
            map.clear();

            updateuser.setOpenid(userObj.getString("openid"));
            updateuser.setOpenid(userObj.getString("unionid"));
            updateuser.setOpenid(userObj.getString("nickname"));
            updateuser.setOpenid(userObj.getString("headimgurl"));
            updateuser.setOpenid(userObj.getString("city"));
            updateuser.setOpenid(userObj.getString("province"));
            updateuser.setCountry(userObj.getString("country"));
            updateuser.setGender(userObj.getString("sex"));
            updateuser.setOriginType(originType);

            map.put("isFocus", "1");

            updateuser.setOpenid(openid);
            updateuser.setIsFocus(1);
            userService.update(updateuser, new EntityWrapper<User>().eq("openid", openid));
        }

        if (qrscene.length > 1) {
            String hbtype = RedisUtils.isExists(qrscene[1]) ? RedisUtils.get(qrscene[1]) : "";
            String txt = "你的粉丝【" + userObj.getString("nickname") +
                    "】通过扫描" + hbtype + "推广海报关注了公众号";
            WeixinUtil.sendCustomMsg(qrscene[0], txt, mpid);
        }
    }

    // 上传素材信息
    public static String uploadTempMaterial(String mpid, String type, String uid, String filepath, String eventKey, Integer expire) {

        String url = (expire == null || expire == 0) ? Constants.WEIXIN_ADD_MATERIAL_URL : Constants.WEIXIN_MATERIAL_UPLOAD_URL;

        url = url.replace("ACCESS_TOKEN", getAccessToken(mpid))
                .replace("TYPE", type);

        logger.debug(">>>>>> uploadTempMaterial filepath=" + filepath);

        String json = HttpUtils.postFile(url, "media", filepath);
        JSONObject jsonObject = JSON.parseObject(json);
        String media_id = jsonObject.getString("media_id");
        Long created_at = jsonObject.getLong("created_at");

        if (Strings.isNullOrEmpty(media_id)) {
            logger.debug(">>>>>> uploadTempMaterial failed");
            return null;
        }

        // 返回media_id
        return media_id;
    }

    // 上传素材信息
    public static JSONObject uploadTempMaterial(String type, String filepath,
                                                Integer expire, String paramKey, String paramValue) {

        String url = (expire == null || expire == 0) ? Constants.WEIXIN_ADD_MATERIAL_URL : Constants.WEIXIN_MATERIAL_UPLOAD_URL;

        url = url.replace("ACCESS_TOKEN", getAccessToken())
                .replace("TYPE", type);

        logger.debug(">>>>>> uploadTempMaterial filepath=" + filepath);
        String json = "";
        if (type.equals("video") && !Strings.isNullOrEmpty(paramKey)) {
            json = HttpUtils.postFile(url, "media", filepath, paramKey, paramValue);
        } else {
            json = HttpUtils.postFile(url, "media", filepath, null, null);
        }

        JSONObject jsonObject = JSON.parseObject(json);
        logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> uploadTempMaterial filepath=" + jsonObject);

//        // 返回media_id
        return jsonObject;
    }

    // 上传素材信息
    public static JSONObject uploadTempMaterial(String type, String filepath, Integer expire, String mpid) {

        String url = (expire == null || expire == 0) ? Constants.WEIXIN_ADD_MATERIAL_URL : Constants.WEIXIN_MATERIAL_UPLOAD_URL;

        url = url.replace("ACCESS_TOKEN", getAccessToken(mpid))
                .replace("TYPE", type);

        logger.debug(">>>>>> uploadTempMaterial filepath=" + filepath);
        String json = "";
        json = HttpUtils.postFile(url, "media", filepath, null, null);

        JSONObject jsonObject = JSON.parseObject(json);
        return jsonObject;
    }

    public static String getQrToken(String token, String sceneStr, String actionName, int expire) {

        JSONObject action = new JSONObject();

        JSONObject actionInfo = new JSONObject();
        JSONObject scene = new JSONObject();

        if (actionName.equals(Constants.WEIXIN_ACTION_NAME_QR_SCENE)) {
            action.put("expire_seconds", expire);
        }
        if (actionName.equals(Constants.WEIXIN_ACTION_NAME_QR_LIMIT_STR_SCENE)) {
            scene.put("scene_str", sceneStr);
        } else {
            try {
                scene.put("scene_id", Integer.valueOf(sceneStr));
            } catch (Exception e) {
                logger.error("can't parse scene to int", e);
            }
        }
        actionInfo.put("scene", scene);

        action.put("action_name", actionName);
        action.put("action_info", actionInfo);

        String ticket = HttpUtils.httpPost(
                Constants.WEIXIN_URL_QRCODE_TICKET.replace("TOKEN", token),
                action.toJSONString());
        return JSON.parseObject(ticket).get("ticket").toString();
    }

    public static void getShowqrcode(String ticket, String fileName) {
        String enTicket = null;
        try {
            enTicket = java.net.URLEncoder.encode(ticket, "utf-8");
        } catch (Exception e) {
            logger.error("encode error'", e);
        }
        String imgurl = Constants.WEIXIN_URL_QRCODE_SHOW.replace("TICKET", enTicket);
        FileUtil.download(imgurl, fileName, true);

    }

    public static void main(String[] args) {

    }

    // 向客户发送消息
    public static void sendCustomMsg(String openid, String msgType, Map data) {

        IRedisService redisService = (IRedisService) SpringUtil.getBean("redisServiceImpl");
        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", redisService.getWxtoken());
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", openid);
        map.put("msgtype", msgType);
        map.put(msgType, data);

        HttpUtils.httpPost(url, JSON.toJSONString(map));
    }

    // 向客户发送消息
    public static void sendCustomMsg(String openid, String type, String mediaId) {

        if (Strings.isNullOrEmpty(mediaId)) return;
        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken());
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", openid);
        map.put("msgtype", type);

        map.put(type, getMediaMap(type, mediaId));
        logger.debug(">>>>>>sendCustomMsg map=" + JSON.toJSONString(map));
        HttpUtils.httpPost(url, JSON.toJSONString(map));
    }

    // 向客户发送消息
    public static void sendMiniCustomMsg(String openid, String title, String pagepath, String thumb_media_id) {

        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken());
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", openid);
        map.put("msgtype", MessageUtil.REQ_MESSAGE_MINIPROGRAMPAGE);

        Map<String, Object> submap = new HashMap<String, Object>();
        submap.put("title", title);
        submap.put("pagepath", pagepath);
        submap.put("thumb_media_id", thumb_media_id);

        map.put(MessageUtil.REQ_MESSAGE_MINIPROGRAMPAGE, submap);

        logger.debug(">>>>>>sendMiniCustomMsg map=" + JSON.toJSONString(map));
        HttpUtils.httpPost(url, JSON.toJSONString(map));
    }

    // 向客户发送消息
    public static void sendCustomMsg(String openid, String type, String mediaId, String mpid) {

        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken(mpid.toString()));
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", openid);
        map.put("msgtype", type);

        map.put(type, getMediaMap(type, mediaId));
        logger.debug(">>>>>>sendCustomMsg map=" + JSON.toJSONString(map));
        HttpUtils.httpPost(url, JSON.toJSONString(map));
    }


    // 向客户发送消息
    public static void zfCustomMsg(String openid, String type, String mediaId, String mpid) {

        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken(mpid.toString()));
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", openid);
        map.put("msgtype", type);

        map.put(type, getMediaMap(type, mediaId));
        logger.debug(">>>>>>sendCustomMsg map=" + JSON.toJSONString(map));
        HttpUtils.httpPost(url, JSON.toJSONString(map));
    }

    // 向客户发送小程序消息
    public static void sendCustomMiniMsg(String openid, String type, String mediaId, String mpid) {

        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken(mpid.toString()));
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("touser", openid);
        map.put("msgtype", type);

        map.put(type, getMediaMap(type, mediaId));
        logger.debug(">>>>>>sendCustomMsg map=" + JSON.toJSONString(map));
        HttpUtils.httpPost(url, JSON.toJSONString(map));
    }

    // 向客户发送文本消息
    public static void sendCustomMsg(String openid, String txt) {

        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken());
        Map<String, Object> map = new HashMap<String, Object>();
        String type = Constants.WEIXIN_MATERIAL_TEXT;
        map.put("touser", openid);
        map.put("msgtype", type);

        map.put(type, getMediaMap(type, txt));
        logger.debug(">>>>>>sendCustomMsg map=" + JSON.toJSONString(map));
        HttpUtils.httpPost(url, JSON.toJSONString(map));
    }
//
//    // 向客户发送文本消息
//    public static void sendCustomMsg(String openid, String txt,Long mpid) {
//
//        String url = Constants.WEIXIN_URL_CUSTOM_SEND.replace("ACCESS_TOKEN", WeixinUtil.getAccessToken(mpid.toString()));
//        Map<String, Object> map = new HashMap<String, Object>();
//        String type = Constants.WEIXIN_MATERIAL_TEXT;
//        map.put("touser", openid);
//        map.put("msgtype", type);
//
//        map.put(type, getMediaMap(type, txt));
//        logger.debug(">>>>>>sendCustomMsg map=" + JSON.toJSONString(map));
//        HttpUtils.httpPost(url, JSON.toJSONString(map));
//    }

    public static void processGroups(String openid, String groupid, String groups) {

        if (com.google.common.base.Strings.isNullOrEmpty(groups)) return;
        JSONArray ja = null;
        try {
            ja = JSON.parseArray(groups);
        } catch (Exception e) {
            logger.error(">>>parseArray(groups) error", e);
            return;
        }

        logger.debug("groups=" + groups);

        for (int m = 0; m < ja.size(); m++) {

            JSONObject jo = ja.getJSONObject(m);
            String gid = jo.getString("id");
            logger.debug("gid=" + gid + " and groupid=" + groupid);

            if (!gid.equals(groupid)) continue;// 只处理管理员自己的群

            JSONArray members = jo.getJSONArray("member");

//            String hmkey = Constants.REDIS_WX_GROUP_MEMBER+groupid+"_"+openid;//redis_key
            String hmkey = Constants.REDIS_WX_GROUP_MEMBER + groupid;//redis_key

            for (int n = 0; n < members.size(); n++) {
                JSONObject member = members.getJSONObject(n);
                String mid = jo.getString("id");
                String displayname = jo.getString("displayname");
                String markname = com.google.common.base.Strings.isNullOrEmpty(jo.getString("markname")) ? displayname : jo.getString("markname");

//                String hmkey = Constants.REDIS_WX_GROUP_MEMBER+groupid;//redis_key
                logger.debug(">>>processGroups hmkey=" + hmkey + " markname=" + markname + " mid=" + mid);
                RedisUtils.setMap(hmkey, markname, mid);
            }

            break;
        }
    }


    public static Map getMediaMap(String type, String mediaId) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (type.equals(Constants.WEIXIN_MATERIAL_IMAGE)
                || type.equals(Constants.WEIXIN_MATERIAL_MPNEWS)
                || type.equals(Constants.WEIXIN_MATERIAL_VOICE)
        ) {
            map.put("media_id", mediaId);
        } else if (type.equals(Constants.WEIXIN_MATERIAL_VIDEO)) {
            map.put("media_id", mediaId);
            map.put("title", "");
            map.put("description", "");
        } else if (type.equals(Constants.WEIXIN_MATERIAL_TEXT)) {
            map.put("content", mediaId);
        } else if (type.equals(Constants.WEIXIN_MATERIAL_WXCARD)) {
            map.put("card_id", mediaId);
        } else if (type.equals(Constants.WEIXIN_MATERIAL_VIDEO)) {
            map.put("card_id", mediaId);
        }

        return map;
    }

    // 生成最新个人二维码 + 用户信息（主要是logo变化）
    public static void checkUserInfo(String openid, String mpid, boolean isNewUser) {

        IUserService userService = (IUserService) SpringUtil.getBean("userServiceImpl");
        logger.debug(">>>>>> start to checkUserQR for userId=" + openid);
        // 判断个人二维码是否存在，不存在获取最新
        String filepath = Constants.WX_QBD_IMAGEPATH_QR + openid + ".jpg";
        String filepathNew = Constants.WX_QBD_IMAGEPATH_QR + openid + "_52B3C0.jpg";
        String filepathNew2 = Constants.WX_QBD_IMAGEPATH_QR + openid + "_6497C7.jpg";

        File file = new File(filepath);
        File file52b3c0 = new File(filepathNew);
        File file6497c7 = new File(filepathNew2);
//        Color fontcolor = new Color (82,179,192);//52b3c0
//        Color fontcolor2 = new Color (130,151,199);//6497c7
        Color fontcolor = ColorUtil.toColor("52b3c0"); //52b3c0
        Color fontcolor2 = ColorUtil.toColor("6497c7");//6497c7
        if (file.exists() && !file52b3c0.exists()) {
            ImageUtil.changeQrColor(filepath, filepathNew, Color.black, fontcolor);
        }
        if (file.exists() && !file6497c7.exists()) {
            ImageUtil.changeQrColor(filepath, filepathNew2, Color.black, fontcolor2);
        }
        logger.debug(">>>>>>checkUserQR changeQrColor1 over ");

        long nowtime = DateUtil.getTime() / 1000;// 精确到秒

        String isCheckUpkey = Constants.REDIS_KEYTYPE_CHECKUSER + openid + "_" + DateUtil.getToday();
        IRedisService redisService = (IRedisService) SpringUtil.getBean("redisServiceImpl");
        String token = redisService.getWxtoken(mpid);
        try {

            if (RedisUtils.isExists(isCheckUpkey)) {
                logger.debug(">>>checkUser return isCheckUpkey =true");
                return;
            } else {
                RedisUtils.set(isCheckUpkey, Constants.REDIS_ONE, 2, TimeUnit.DAYS);
            }

            RMap<String, String> rmap = RedisUtils.getRMap("qrimage_" + openid);
            String qrpath = rmap.get(openid + "_path");

            if (!file.exists()) {
                rmap.remove("path");
                rmap.remove("createtime");
                rmap.remove("expire");
                qrpath = null;
            }

            // 检查用户logo是否变更
            JSONObject user = WeixinUtil.getWXUserInfo(openid, mpid);
            if (user == null) {
                logger.debug(">>>checkUser return for user==null");
                return;
            }
            logger.debug(">>>>>>checkUserQR user= " + JSON.toJSONString(user));

            Map<String, Object> map = new HashMap<String, Object>();
            if (user.getIntValue("errcode") == 40003) {//invalid openid hint

                map.put("openid", openid);
                map.put("isfocus", 0);
                User updateuser = new User();
                updateuser.setOpenid(openid);
                updateuser.setIsFocus(0);

                userService.update(updateuser, new EntityWrapper<User>().eq("openid", openid));
                logger.debug(">>>checkUser errcode 40003");
                return;
            }

            String ruserlogo = RedisUtils.get(Constants.REDIS_USER_LOGO + openid);

            logger.debug(">>>checkUser ruserlogo=" + ruserlogo + " headimgurl="
                    + user.getString("headimgurl") + " for user=" + openid);

            if (Strings.isNullOrEmpty(ruserlogo) || ruserlogo.equals("null") ||
                    !user.getString("headimgurl").equals(ruserlogo)) {

                logger.debug(">>>checkUser set headimgurl=" + user.getString("headimgurl") + " for user=" + openid);
                RedisUtils.set(Constants.REDIS_USER_LOGO + openid, user.getString("headimgurl"));

                map.clear();
                map.put("openid", openid);
                map.put("avatarUrl", user.getString("headimgurl"));
                map.put("unionid", user.getString("unionid"));
                User updateuser = new User();
                updateuser.setOpenid(openid);
                updateuser.setAvatarPic(user.getString("headimgurl"));
                updateuser.setUnionid(user.getString("unionid"));

                userService.update(updateuser, new EntityWrapper<User>().eq("openid", openid));
            }

            // update person qr
            logger.debug(">>>checkUserQR update person qr ");

            boolean isUpdateQR = true;
            if (!Strings.isNullOrEmpty(qrpath)) {
                String createtime = rmap.get("createtime");
                String expire = rmap.get("expire");
                logger.debug(">>>>>> checkUserQR qrimage=" + qrpath + " createtime=" + createtime + " expire=" + expire + " nowtime=" + String.valueOf(nowtime));

                if (nowtime - Long.valueOf(createtime) < Long.valueOf(expire)) {
                    isUpdateQR = false;
                }
            }
            logger.debug(">>>>>>isUpdateQR =" + isUpdateQR);

            if (isUpdateQR) {
                // 获取最新个人二维码
                String url = Constants.WEIXIN_URL_QRCODE_TICKET.replace("TOKEN", token);
//            map.put("expire_seconds", 2592000);// 30天
                map.put("expire_seconds", 259200);// 3天
//        map.put("action_name","QR_SCENE");
                map.put("action_name", "QR_STR_SCENE");
                JSONObject action = new JSONObject();
                JSONObject scene = new JSONObject();
//        scene.put("scene_id", Constants.WEIXIN_SCENE_QBD);
                scene.put("scene_str", openid);
                action.put("scene", scene);
                map.put("action_info", action);

                String result = HttpUtils.httpPost(url, JSON.toJSONString(map));
                logger.debug(">>>>>> checkUserQR result=" + result);

                JSONObject json = JSON.parseObject(result);
                String ticket = json.getString("ticket");
                String qrurl = Constants.WEIXIN_URL_QRCODE_SHOW.replace("TICKET", URLEncoder.encode(ticket));
                // 下载保存二维码到本地文件
                HttpUtils.downloadFile(qrurl, filepath);

                logger.debug(">>>>>> checkUserQR start to changeQrColor");
                ImageUtil.changeQrColor(filepath, filepathNew, Color.black, fontcolor);
                ImageUtil.changeQrColor(filepath, filepathNew2, Color.black, fontcolor2);

                // 写入redis
                logger.debug(">>>>>> write to redisfilepath=" + filepath);

                rmap.put("path", filepath);
                rmap.put("createtime", String.valueOf(nowtime));
//            rmap.put(openid + "expire", "2592000");//30天，以秒为单位
                rmap.put("expire", "259200");//3天，以秒为单位

                logger.debug(">>>>>>set redismap qrimage ok");
            }

            // change qrImage color

            // 更新checkUpUser值
            if (isNewUser) {
                logger.debug(">>>>>> notify akka to create template");

                // 最后参数代表是否通知用户
//                AkkaServer.system.actorOf(Props.create(AKRealTemplate.class))
//                        .tell(Constants.WX_EVT_WISDOM + "@" + openid + "@" + mpid + "@false", ActorRef.noSender());

//                AkkaServer.system.actorOf(Props.create(AKRealTemplate.class)).tell(Constants.WX_EVT_ENGLISH + "@" + openid + "@" + mpid + "@false", ActorRef.noSender());

                RedisUtils.set(isCheckUpkey, Constants.REDIS_ONE, 2, TimeUnit.DAYS);
            }
            logger.debug(">>>>>> checkUserQR over");
        } catch (Exception e) {
            logger.error(">>>checkUser error", e);
        }
    }

    public static Map getSignMap(String openid) {
//
//        // 计算连续签到
//        logger.debug(">>>getSignMap");
//        String isZaoqiKey = Constants.REDIS_KEYTYPE_IS_ZAOQIN + openid + "_" + DateUtil.getToday();
//        String zaoqi = RedisUtils.get(isZaoqiKey);
//        if (Strings.isNullOrEmpty(zaoqi)
//                || !zaoqi.equals("1")) return null;
//
//        logger.debug(">>>getSignMap 2");
//        RedisUtils.set(isZaoqiKey, "2", 1, TimeUnit.DAYS);
//
//        String repeatSignKey = Constants.REDIS_USER_REPEAT_SIGN + openid;
//
//        Long newRepeatDays = 1l;
//        boolean isRepeatDaysInRedis = false;
//
//        if (RedisUtils.isExists(repeatSignKey)) {
//            isRepeatDaysInRedis = true;
//            newRepeatDays = RedisUtils.getLong(repeatSignKey) + 1l;
//            logger.debug(">>>>>>getSignMap isRepeatDaysInRedis=true set newRepeatDays=" + newRepeatDays + " for repeatSignKey=" + repeatSignKey);
//            RedisUtils.setLong(repeatSignKey, newRepeatDays);
//        }
//
//        Map map = new HashMap<String, Object>();
//        String date = DateUtil.getToday();
//        map.put("openid", openid);
//        map.put("signinTime", date);
//        map.put("stype", 1);
//
//        SigninMapper signinMapper = (SigninMapper) SpringUtil.getObject("signinMapper");
//        // 查询今日第一次早起签到
//        java.util.List<SigninDO> signins = signinMapper.selectSignin(map);
//        if (signins.size() == 0) {
//            logger.debug(">>>>>> signin is not in signin time");
//            return null;
//        }
//        SigninDO signin = signins.get(0);
//        logger.debug(">>>>>> signin signin object toString() " + JSON.toJSONString(signin));
//
//        if (!isRepeatDaysInRedis) {
//            newRepeatDays = Long.valueOf(calcRepeatDay(openid));
//            logger.debug(">>>>>>getSignMap isRepeatDaysInRedis=false set newRepeatDays=" + newRepeatDays);
//            RedisUtils.setLong(repeatSignKey, newRepeatDays);
//        }
//
//        // 计算打卡排名
//        map.clear();
//        map.put("openid", openid);
//        UserMapper userMapper = (UserMapper) SpringUtil.getObject("userMapper");
//        User user = userMapper.selectUser(map);
//        map.put("poid", user.getPoid());
//
//        map.clear();
//        map.put(PictureUtil.SIGN_DATE, date);
//        map.put(PictureUtil.SIGN_TIME, DateUtil.toDateString(signin.getSigninTime(), "HH:mm:ss"));
////        map.put(PictureUtil.SIGN_RANKING,"连续打卡第"+newRepeatDays+"天  好友早起排名第"+rank);
//        map.put(PictureUtil.SIGN_RANKING, "连续签到第" + newRepeatDays + "天 只为梦想 只为那份坚持");
////        map.put(PictureUtil.SIGN_RANKING,"连续签到第"+newRepeatDays+"天 日拱一卒 水滴石穿");
//
//        WisdomService wisdomService = (WisdomService) SpringUtil.getObject("wisdomService");
//        String motto = wisdomService.randomWisdom().getContent();
//        map.put(PictureUtil.SIGN_MOTTO, motto.trim());
//
//        return map;
        return null;
    }

    public static int calcRepeatDay(String uid) {

        int newRepeatDays = 1;

        Map map = new HashMap<String, Object>();
        map.put("orderBy", "signinTime");
        map.put("order", "desc");
        map.put("offset", 0);
        map.put("pageSize", 200);
        map.put("uid", uid);
        map.put("stype", "1");

        //待完善20190101
//        SigninMapper signinMapper = (SigninMapper) SpringUtil.getObject("signinMapper");
//        List<SigninDO> signs = signinMapper.selectSigninList(map);
//        logger.debug(">>>>>>calcRepeatDay signs size = " + signs.size());
//        if (signs != null && signs.size() > 0) {
//            SigninDO firstSign = signs.get(0);
//            if (signs.size() > 1) {
//                String firstDate = DateUtil.toDateString(firstSign.getSigninTime(), "YYYY-MM-dd");
//                for (int i = 1; i < signs.size(); i++) {
//                    String datestr = DateUtil.toDateString(DateUtil.addDay(signs.get(i).getSigninTime(), i), "YYYY-MM-dd");
//                    logger.debug(">>>>>> signin datestr=" + datestr + " firstDate=" + firstDate + " @ i=" + i);
//                    if (datestr.equals(firstDate)) {
//                        newRepeatDays++;
//                    } else {
//                        break;
//                    }
//                }
//            }
//        }
        return newRepeatDays;
    }

    public static English randomEnglish() {

        IEnglishService englishService = (IEnglishService) SpringUtil.getBean("englishServiceImpl");
        int count;
        if (Constants.conMap.containsKey("EnglishCount")) {
            count = (int) Constants.conMap.get("EnglishCount");
        } else {
            Map<String, Object> qmap = new HashMap<String, Object>();
            qmap.put("pathNotNull", 1);
            count = englishService.selectCount(new EntityWrapper<English>());
            Constants.conMap.put("EnglishCount", count);
        }
        Random ram = new Random();
        int skip = ram.nextInt(count);

        return englishService.selectRandomEnglish(skip);
    }


    public static Map<String, String> getEverShowqrcode(String wxtype, String sceneStr, int expire) {

        String url = Constants.WEIXIN_URL_QRCODE_TICKET.replace("TOKEN", getAccessToken());
        Map map = new HashMap<String, String>();

        if (expire == 0) {
            // 永久二维码
            map.put("action_name", "QR_LIMIT_STR_SCENE");

        } else {
            // 短期二维码
            map.put("action_name", "QR_STR_SCENE");
//            map.put("expire_seconds", 2592000);// 30天
            map.put("expire_seconds", expire);// 30天
        }

        JSONObject action = new JSONObject();
        JSONObject scene = new JSONObject();
        scene.put("scene_str", sceneStr);
        action.put("scene", scene);
        map.put("action_info", action);

        String result = HttpUtils.httpPost(url, JSON.toJSONString(map));
        logger.debug(">>>>>> checkUserQR result=" + result);

        JSONObject json = JSON.parseObject(result);
        String ticket = json.getString("ticket");
        String qrurl = Constants.WEIXIN_URL_QRCODE_SHOW.replace("TICKET", URLEncoder.encode(ticket));

        String filepath = "/images/qr/" + sceneStr + "_qr.jpg";
        // 下载保存二维码到本地文件
        HttpUtils.downloadFile(qrurl, "/fafa/www" + filepath);
//        try {
//            Runtime.getRuntime().exec("chmod 644 " + "/fafa/www"+filepath);
//        } catch (IOException e) {
//            logger.error("chmod 644 " + filepath + " error", e);
//        }
        map.clear();
        map.put("localpath", "/fafa/www" + filepath);
        map.put("sitepath", "http://www.51hewei.com/" + filepath);
//        return "http://www.51hewei.com/"+filepath;
        return map;
    }

    // 获取上级是否会过会员
    public static String getPuserKey(String openid, String key, String ptype) {

        String rkey = key;
        Map map = new HashMap<String, Object>();
        map.put("openid", openid);

//        User user = userMapper.selectUser(map);
//
//        if (user.getUserType() == 1) {
//            rkey = key;
//        } else if (user.isHuiguo()) {
//            rkey = key + "_" + user.getOpenid();
//        } else {
//            map.put(ptype, 1);
//            List<User> pusers = userMapper.selectSuperUsers(map);
//            if (pusers.size() > 0)
//                rkey = pusers.get(0).getUserType() == 1 ? key : key + "_" + pusers.get(0).getOpenid();
//        }

        return rkey;
    }

    public static void addEvtredis(String uid, String evtType, String queryInfo, Integer expire, TimeUnit tu) {

        long ts = DateUtil.getTime();
        if (!Strings.isNullOrEmpty(queryInfo)) {
            RedisUtils.set(Constants.REDIS_SESSION_TYPE + uid + "_" + ts, queryInfo, expire, tu);
        }

        RedisUtils.setList(Constants.REDIS_SESSION_TYPE + uid, Constants.REDIS_EVENT + evtType + "_" + ts);
    }

    /*
     * 清除redis缓存
     */
    public static void delEvtredis(String uid, String evtType) {

        RList<String> list = RedisUtils.getList(Constants.REDIS_SESSION_TYPE + uid);
        if (list == null || list.size() == 0) {
            return;
        }
        String lastVal = list.get(list.size() - 1);
        RedisUtils.deleteList(Constants.REDIS_SESSION_TYPE + uid, lastVal);

        logger.debug(">>>>>>delEvtredis lastVal=" + lastVal);

        // format:inputType_inputInfo_matchType_timestamp
        // event_ribao_1502862671761
        String[] arrs = lastVal.split("_");
        String inputType = arrs[0];
        String matchType = arrs[1];
        String timeStamp = arrs[2];
        if (RedisUtils.isExists(Constants.REDIS_SESSION_TYPE + uid + "_" + timeStamp)) {
            RedisUtils.delete(Constants.REDIS_SESSION_TYPE + uid + "_" + timeStamp);
        }
    }

    public static Boolean replayKeyWord(String content, String openid, String mpid) {

        String mediaId = RedisUtils.get(content.toLowerCase());
        logger.debug(">>>replayProduct=" + content);

        String replayTxt = null;
        boolean result = true;

        if (content.toLowerCase().startsWith("hg")) {
            replayTxt = Constants.EMOJI_CLOVER + "领取方法：\n打开商品图片长按识别小程序码"
                    + "\n进入商城购买领取10元优惠券"
                    + "\n(以20元商品为例)下单支付10元购买"
                    + "\n支付成功后截图给公众号"
                    + "\n将返你5元红包"
                    + "\n最终您只花5元购买商品"
                    + "\n\n注意：每个用户只限购领一次"
                    + "\n活动真实有效"
                    + "\n如未出现商品图片，请重新回复关键词"
                    + "\n如未出现直接购买按钮，请关闭商城重新进入";

            RedisUtils.set("hg_user_" + openid, "1", 10, TimeUnit.DAYS);
            RList<String> list = RedisUtils.getList(Constants.REDIS_SESSION_TYPE + openid);
            for (String item : list) {
                RedisUtils.deleteList(Constants.REDIS_SESSION_TYPE + openid, item);
            }

            String key = WeixinUtil.getPuserKey(openid, content.toLowerCase(), "isHuiguo");
            logger.debug(">>>key=" + key + " and RedisUtils.isExists(key)=" + RedisUtils.isExists(key));
            mediaId = RedisUtils.isExists(key) ? RedisUtils.get(key) : mediaId;
            WeixinUtil.sendCustomMsg(openid, Constants.WEIXIN_MATERIAL_IMAGE, mediaId);
        } else if (content.trim().equals("2019")) {
            long getcout = RedisUtils.getLong("yuanmeng_get_" + openid);
            logger.debug(">>>getcout=" + getcout);
            if (getcout < 3) {
                getcout++;
                RList<String> rlist = RedisUtils.getList("yuanmeng_2018");
                int cout = rlist.size();
                Random random = new Random();
                String mengid = rlist.get(random.nextInt(cout));
                WeixinUtil.sendCustomMsg(openid, Constants.WEIXIN_MATERIAL_IMAGE, mengid);
                RedisUtils.setLong("yuanmeng_get_" + openid, getcout);
                return null;
            } else {
                replayTxt = "2019的小目标不用太多哦\n老子曰：多则惑，少则得";
            }
        } else if (content.trim().equals("牛牛牛")) {
            String mediaid = RedisUtils.get("niuniuniu_" + openid);
            if (mediaid == null) {
                logger.info("=====Constants.WX_NIUNIUNIU");
                AkkaServer.system.actorOf(Props.create(AKRealTemplate.class))
                        .tell(Constants.WX_NIUNIUNIU + "@" + openid + "@" + mpid + "@true", ActorRef.noSender());
            } else {
                WeixinUtil.sendCustomMsg(openid, Constants.WEIXIN_MATERIAL_IMAGE, mediaid);
            }
        } else {
            result = false;
        }

        if (!Strings.isNullOrEmpty(replayTxt)) {
            WeixinUtil.sendCustomMsg(openid, replayTxt, Constants.WEIXIN_QIANBAIDU);
        }

        return result;
    }

}
